package cn.melonlib.cores.jpa.comp.dao.db.maps;

import cn.melonlib.cores.commons.model.entity.IEntity;
import cn.melonlib.cores.jpa.comp.dao.db.DatabaseTypeMaps;
import cn.melonlib.cores.jpa.model.bean.collections.DataMap;
import lombok.Getter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.persistence.Column;
import javax.persistence.Lob;
import java.lang.reflect.Field;
import java.util.Date;
import java.util.function.Function;

@Component
@Getter
@ConditionalOnProperty(value = "jdbc.driver-class-name",havingValue = "org.mariadb.jdbc.Driver",matchIfMissing = false)
public class MariadbFieldTypeMaps implements DatabaseTypeMaps {

    private DataMap<Class<?>, Function<Field,String>> typeMaps=new DataMap<>();

    private final String template="db_schemas/create_comment_mariadb.ftl";

    @PostConstruct
    public void init(){
        typeMaps.append(Integer.class,f->"int(11)");
        typeMaps.append(Long.class,f->"bigint(20)");
        typeMaps.append(Double.class,f->"double");
        typeMaps.append(Boolean.class,f->"bit(1)");
        typeMaps.append(IEntity.class, f->"varchar(100)");
        typeMaps.append(Enum.class,f->"varchar(100)");
        typeMaps.append(Date.class, f->"timestamp");
        typeMaps.append(String.class,f->{
            Column column=AnnotationUtils.findAnnotation(f, Column.class);
            Lob lob=AnnotationUtils.findAnnotation(f, Lob.class);
            if (lob != null) {
                return "longtext";
            }
            Integer length=column!=null?column.length():255;
            return new StringBuilder("varchar(").append(length).append(")").toString();
        });
    }

    @Override
    public String map(Field field) {
        try {
            if(IEntity.class.isAssignableFrom(field.getType())){
                return typeMaps.get(IEntity.class).apply(field);
            }
            if(field.getType().isEnum()){
                return typeMaps.get(Enum.class).apply(field);
            }
            return typeMaps.get(field.getType()).apply(field);
        }catch (Exception e){
            throw e;
        }
    }

    @Override
    public String getDbName() {
        return "MariaDB";
    }
}
